﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

public class RefPrint
{
    public static PrintLog PrintTool;

    private static StringBuilder sb = new StringBuilder();

    public static void PrintClassInfo<T>(T obj) where T : class
    {
        if (obj == null) {
            PrintTool.WriteLine("print class of null");
            return;
        }
        sb = new StringBuilder();
        sb = sb.AppendLine(obj.GetType().Name);
        Type t = obj.GetType();
        PrintFields(t, obj);
        PrintTool.WriteLine(sb.ToString());
    }

    public static void PrintClassInfo(object obj)
    {
        if (obj == null)
        {
            PrintTool.WriteLine("print class of null");
            return;
        }

        sb = new StringBuilder();
        sb = sb.AppendLine(obj.GetType().Name);
        Type t = obj.GetType();
        PrintFields(t, obj);
        PrintTool.WriteLine(sb.ToString());
    }


    public static void PrintList(object listValue)
    {
        IEnumerable e = listValue as IEnumerable;
        FieldInfo[] fList = null;
        foreach (var c in e)
        {
            fList = c.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
            foreach (var item in fList)
            {
                sb = sb.AppendLine(item.FieldType.Name + "\t" + item.Name + "\t" + item.GetValue(c).ToString());
            }
        }
    }

    public static void PrintAry(object aryValue)
    {
        IEnumerable e = aryValue as IEnumerable;
        FieldInfo[] fList = null;
        foreach (var c in e)
        {
            if (c.GetType().Name.Contains("String"))
            {
                sb = sb.AppendLine(c.GetType().Name + "\t" + c);
            }
            else if (!c.GetType().Name.Contains("String") && c.GetType().IsClass)
            {
                fList = c.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
                foreach (var item in fList)
                {
                    sb = sb.AppendLine(item.FieldType.Name + "\t" + item.Name + "\t" + item.GetValue(c));
                }
            }
            else
            {
                sb.AppendLine(c.GetType().Name + "\t" + c + "\t");
            }
        }
    }


    public static void PrintMemebers(Type t, object value)
    {
        var mList = t.GetMembers();

        foreach (var item in mList)
        {
            sb = sb.AppendLine("method: " + item.Name);
        }
    }

    public static void PrintFields(Type t, object value)
    {
        var fList = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        foreach (var item in fList)
        {
            if (!item.FieldType.IsClass || (item.FieldType.Name == "String"))
                sb = sb.AppendLine(item.FieldType.Name + "\t" + item.Name + "\t" + item.GetValue(value));

            if (item.FieldType.Name.Contains("List"))
            {
                sb = sb.AppendLine("集合" + item.Name + ":");
                Object listValue = item.GetValue(value);
                PrintList(listValue);
            }

            if (item.FieldType.Name.Contains("[]"))
            {
                sb = sb.AppendLine("数组" + item.Name + ":");
                Object aryValue = item.GetValue(value);
                PrintAry(aryValue);
            }
        }
    }

    public static void PrintProperties(Type t, object value)
    {
        var pList = t.GetProperties();

        foreach (var item in pList)
        {
            sb = sb.AppendLine(item.Name + " " + item.GetValue(value, new object[] { }));
        }
    }
}

public interface PrintLog
{
    void WriteLine(string text);
}